package com.huawei.spare.part.replace.views.dashboard;

import com.huawei.spare.part.replace.framework.SmartDataBus;
import com.huawei.spare.part.replace.framework.SmartPresenter;
import com.huawei.spare.part.replace.framework.SmartRouter;
import io.reactivex.rxjavafx.observables.JavaFxObservable;
import io.reactivex.rxjavafx.schedulers.JavaFxScheduler;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.geometry.Rectangle2D;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import lombok.Getter;

import java.util.concurrent.TimeUnit;

@Getter
public class DashboardPresenter extends SmartPresenter {

    // decorator buttons
    @FXML
    private Button maximize;

    @FXML
    private ListView<SmartRouter.Menu> menu;

    // Title
    @FXML
    private Label title;

    // Footer
    @FXML
    private HBox footer;
    @FXML
    private Button previousStep;
    @FXML
    private Button nextStep;
    @FXML
    private Button exitStep;

    // Content
    @FXML
    private StackPane content;


    public void initialize() {
        SmartRouter.initialize(this);
        ObservableList<SmartRouter.Menu> menuItems = FXCollections.observableArrayList(SmartRouter.Menu.values());
        menu.setItems(menuItems);
        Platform.runLater(() -> {
            menu.getSelectionModel().select(0);
            menu.requestFocus();

            JavaFxObservable.eventsOf(this.nextStep, ActionEvent.ACTION)
                            .debounce(300, TimeUnit.MILLISECONDS)
                            .observeOn(JavaFxScheduler.platform())
                            .subscribe(this::onNextStep);
            JavaFxObservable.eventsOf(this.previousStep, ActionEvent.ACTION)
                            .debounce(300, TimeUnit.MILLISECONDS)
                            .observeOn(JavaFxScheduler.platform())
                            .subscribe(this::onPreviousStep);

            JavaFxObservable.eventsOf(this.exitStep, ActionEvent.ACTION)
                            .debounce(300, TimeUnit.MILLISECONDS)
                            .observeOn(JavaFxScheduler.platform())
                            .subscribe(this::onExit);
            SmartRouter.get().route(SmartRouter.Menu.Home);
        });
    }

    @FXML
    private void handleMenuClicked(MouseEvent event) {
        SmartRouter.Menu menu = this.menu.getSelectionModel().getSelectedItem();
        if (menu != null) {
            SmartRouter.get().route(menu);
        }
    }

    @FXML
    private void onNextStep(ActionEvent event) {
        this.getFooter().setDisable(true);
        SmartRouter.get().routeToNextView();
        this.getFooter().setDisable(false);
    }

    @FXML
    private void onPreviousStep(ActionEvent event) {
        this.getFooter().setDisable(true);
        SmartRouter.get().routeToPreviousView();
        this.getFooter().setDisable(false);
    }

    @FXML
    private void onMaximize(ActionEvent event) {
        Stage stage = SmartDataBus.get().getStage();
        if (stage.isMaximized()) {
            stage.setMaximized(false);
            maximize.getStyleClass().remove("decoration-button-restore");
        } else {
            Rectangle2D screen = Screen.getPrimary().getVisualBounds();
            ;
            stage.setMaximized(true);
            stage.setHeight(screen.getHeight());
            maximize.getStyleClass().add("decoration-button-restore");
        }
    }

    @FXML
    private void onMinimize(ActionEvent event) {
        final Stage stage = SmartDataBus.get().getStage();
        Platform.runLater(() -> {
            stage.setIconified(true);
        });
    }

    @FXML
    private void onExit(ActionEvent event) {
        final Stage stage = SmartDataBus.get().getStage();
        stage.fireEvent(
                new WindowEvent(
                        stage,
                        WindowEvent.WINDOW_CLOSE_REQUEST
                )
        );
    }

}
